File: //proc/self/cwd/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-internallinks.php
<?php
/**
* @package WPSEO\Internals\Options
*/
/**
* Option: wpseo_internallinks
*/
class WPSEO_Option_InternalLinks extends WPSEO_Option {
/**
* @var string option name
*/
public $option_name = 'wpseo_internallinks';
/**
* @var array Array of defaults for the option
* Shouldn't be requested directly, use $this->get_defaults();
* @internal Note: Some of the default values are added via the translate_defaults() method
*/
protected $defaults = array(
'breadcrumbs-404crumb' => '', // Text field.
'breadcrumbs-blog-remove' => false,
'breadcrumbs-boldlast' => false,
'breadcrumbs-archiveprefix' => '', // Text field.
'breadcrumbs-enable' => false,
'breadcrumbs-home' => '', // Text field.
'breadcrumbs-prefix' => '', // Text field.
'breadcrumbs-searchprefix' => '', // Text field.
'breadcrumbs-sep' => '»', // Text field.
/**
* Uses enrich_defaults() to add more along the lines of:
* - 'post_types-' . $pt->name . '-maintax' => 0 / string
* - 'taxonomy-' . $tax->name . '-ptparent' => 0 / string
*/
);
/**
* @var array Array of variable option name patterns for the option
*/
protected $variable_array_key_patterns = array(
'post_types-',
'taxonomy-',
);
/**
* Get the singleton instance of this class
*
* @return object
*/
public static function get_instance() {
if ( ! ( self::$instance instanceof self ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Translate strings used in the option defaults
*
* @return void
*/
public function translate_defaults() {
$this->defaults['breadcrumbs-404crumb'] = __( 'Error 404: Page not found', 'wordpress-seo' );
$this->defaults['breadcrumbs-archiveprefix'] = __( 'Archives for', 'wordpress-seo' );
$this->defaults['breadcrumbs-home'] = __( 'Home', 'wordpress-seo' );
$this->defaults['breadcrumbs-searchprefix'] = __( 'You searched for', 'wordpress-seo' );
}
/**
* Add dynamically created default options based on available post types and taxonomies
*
* @return void
*/
public function enrich_defaults() {
// Retrieve all the relevant post type and taxonomy arrays.
$post_type_names = get_post_types( array( 'public' => true ), 'names' );
$taxonomy_names_custom = get_taxonomies( array( 'public' => true, '_builtin' => false ), 'names' );
if ( $post_type_names !== array() ) {
foreach ( $post_type_names as $pt ) {
$pto_taxonomies = get_object_taxonomies( $pt, 'names' );
if ( $pto_taxonomies !== array() ) {
$this->defaults[ 'post_types-' . $pt . '-maintax' ] = 0; // Select box.
}
unset( $pto_taxonomies );
}
unset( $pt );
}
if ( $taxonomy_names_custom !== array() ) {
foreach ( $taxonomy_names_custom as $tax ) {
$this->defaults[ 'taxonomy-' . $tax . '-ptparent' ] = 0; // Select box;.
}
unset( $tax );
}
}
/**
* Validate the option
*
* @param array $dirty New value for the option.
* @param array $clean Clean value for the option, normally the defaults.
* @param array $old Old value of the option.
*
* @return array Validated clean value for the option to be saved to the database
*/
protected function validate_option( $dirty, $clean, $old ) {
$allowed_post_types = $this->get_allowed_post_types();
foreach ( $clean as $key => $value ) {
$switch_key = $this->get_switch_key( $key );
switch ( $switch_key ) {
/* text fields */
case 'breadcrumbs-404crumb':
case 'breadcrumbs-archiveprefix':
case 'breadcrumbs-home':
case 'breadcrumbs-prefix':
case 'breadcrumbs-searchprefix':
case 'breadcrumbs-sep':
if ( isset( $dirty[ $key ] ) ) {
$clean[ $key ] = wp_kses_post( $dirty[ $key ] );
}
break;
/* 'post_types-' . $pt->name . '-maintax' fields */
case 'post_types-':
$post_type = str_replace( array( 'post_types-', '-maintax' ), '', $key );
$taxonomies = get_object_taxonomies( $post_type, 'names' );
if ( isset( $dirty[ $key ] ) ) {
if ( $taxonomies !== array() && in_array( $dirty[ $key ], $taxonomies, true ) ) {
$clean[ $key ] = $dirty[ $key ];
}
elseif ( (string) $dirty[ $key ] === '0' || (string) $dirty[ $key ] === '' ) {
$clean[ $key ] = 0;
}
elseif ( sanitize_title_with_dashes( $dirty[ $key ] ) === $dirty[ $key ] ) {
// Allow taxonomies which may not be registered yet.
$clean[ $key ] = $dirty[ $key ];
}
else {
if ( isset( $old[ $key ] ) ) {
$clean[ $key ] = sanitize_title_with_dashes( $old[ $key ] );
}
if ( function_exists( 'add_settings_error' ) ) {
/**
* @todo [JRF => whomever] maybe change the untranslated $pt name in the
* error message to the nicely translated label ?
*/
add_settings_error(
$this->group_name, // Slug title of the setting.
'_' . $key, // Suffix-id for the error message box.
sprintf( __( 'Please select a valid taxonomy for post type "%s"', 'wordpress-seo' ), $post_type ), // The error message.
'error' // Error type, either 'error' or 'updated'.
);
}
}
}
elseif ( isset( $old[ $key ] ) ) {
$clean[ $key ] = sanitize_title_with_dashes( $old[ $key ] );
}
unset( $taxonomies, $post_type );
break;
/* 'taxonomy-' . $tax->name . '-ptparent' fields */
case 'taxonomy-':
if ( isset( $dirty[ $key ] ) ) {
if ( $allowed_post_types !== array() && in_array( $dirty[ $key ], $allowed_post_types, true ) ) {
$clean[ $key ] = $dirty[ $key ];
}
elseif ( (string) $dirty[ $key ] === '0' || (string) $dirty[ $key ] === '' ) {
$clean[ $key ] = 0;
}
elseif ( sanitize_key( $dirty[ $key ] ) === $dirty[ $key ] ) {
// Allow taxonomies which may not be registered yet.
$clean[ $key ] = $dirty[ $key ];
}
else {
if ( isset( $old[ $key ] ) ) {
$clean[ $key ] = sanitize_key( $old[ $key ] );
}
if ( function_exists( 'add_settings_error' ) ) {
/**
* @todo [JRF =? whomever] maybe change the untranslated $tax name in the
* error message to the nicely translated label ?
*/
$tax = str_replace( array( 'taxonomy-', '-ptparent' ), '', $key );
add_settings_error(
$this->group_name, // Slug title of the setting.
'_' . $tax, // Suffix-id for the error message box.
sprintf( __( 'Please select a valid post type for taxonomy "%s"', 'wordpress-seo' ), $tax ), // The error message.
'error' // Error type, either 'error' or 'updated'.
);
unset( $tax );
}
}
}
elseif ( isset( $old[ $key ] ) ) {
$clean[ $key ] = sanitize_key( $old[ $key ] );
}
break;
/*
Boolean fields
*/
/*
Covers:
* 'breadcrumbs-blog-remove'
* 'breadcrumbs-boldlast'
* 'breadcrumbs-enable'
*/
default:
$clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : false );
break;
}
}
return $clean;
}
/**
* Retrieve a list of the allowed post types as breadcrumb parent for a taxonomy
* Helper method for validation
*
* @internal don't make static as new types may still be registered
*
* @return array
*/
protected function get_allowed_post_types() {
$allowed_post_types = array();
$post_types = get_post_types( array( 'public' => true ), 'objects' );
if ( get_option( 'show_on_front' ) == 'page' && get_option( 'page_for_posts' ) > 0 ) {
$allowed_post_types[] = 'post';
}
if ( is_array( $post_types ) && $post_types !== array() ) {
foreach ( $post_types as $type ) {
if ( $type->has_archive ) {
$allowed_post_types[] = $type->name;
}
}
}
return $allowed_post_types;
}
/**
* Clean a given option value
*
* @param array $option_value Old (not merged with defaults or filtered) option value to
* clean according to the rules for this option.
* @param string $current_version (optional) Version from which to upgrade, if not set,
* version specific upgrades will be disregarded.
* @param array $all_old_option_values (optional) Only used when importing old options to have
* access to the real old values, in contrast to the saved ones.
*
* @return array Cleaned option
*/
protected function clean_option( $option_value, $current_version = null, $all_old_option_values = null ) {
/* Make sure the old fall-back defaults for empty option keys are now added to the option */
if ( isset( $current_version ) && version_compare( $current_version, '1.5.2.3', '<' ) ) {
if ( has_action( 'init', array( 'WPSEO_Options', 'bring_back_breadcrumb_defaults' ) ) === false ) {
add_action( 'init', array( 'WPSEO_Options', 'bring_back_breadcrumb_defaults' ), 3 );
}
}
/*
Make sure the values of the variable option key options are cleaned as they
may be retained and would not be cleaned/validated then
*/
if ( is_array( $option_value ) && $option_value !== array() ) {
$allowed_post_types = $this->get_allowed_post_types();
foreach ( $option_value as $key => $value ) {
$switch_key = $this->get_switch_key( $key );
// Similar to validation routine - any changes made there should be made here too.
switch ( $switch_key ) {
/* 'post_types-' . $pt->name . '-maintax' fields */
case 'post_types-':
$post_type = str_replace( array( 'post_types-', '-maintax' ), '', $key );
$taxonomies = get_object_taxonomies( $post_type, 'names' );
if ( $taxonomies !== array() && in_array( $value, $taxonomies, true ) ) {
$option_value[ $key ] = $value;
}
elseif ( (string) $value === '0' || (string) $value === '' ) {
$option_value[ $key ] = 0;
}
elseif ( sanitize_title_with_dashes( $value ) === $value ) {
// Allow taxonomies which may not be registered yet.
$option_value[ $key ] = $value;
}
unset( $taxonomies, $post_type );
break;
/* 'taxonomy-' . $tax->name . '-ptparent' fields */
case 'taxonomy-':
if ( $allowed_post_types !== array() && in_array( $value, $allowed_post_types, true ) ) {
$option_value[ $key ] = $value;
}
elseif ( (string) $value === '0' || (string) $value === '' ) {
$option_value[ $key ] = 0;
}
elseif ( sanitize_key( $option_value[ $key ] ) === $option_value[ $key ] ) {
// Allow post types which may not be registered yet.
$option_value[ $key ] = $value;
}
break;
}
}
}
return $option_value;
}
/**
* With the changes to v1.5, the defaults for some of the textual breadcrumb settings are added
* dynamically, but empty strings are allowed.
* This caused issues for people who left the fields empty on purpose relying on the defaults.
* This little routine fixes that.
* Needs to be run on 'init' hook at prio 3 to make sure the defaults are translated.
*/
public function bring_back_defaults() {
$option = get_option( $this->option_name );
$values_to_bring_back = array(
'breadcrumbs-404crumb',
'breadcrumbs-archiveprefix',
'breadcrumbs-home',
'breadcrumbs-searchprefix',
'breadcrumbs-sep',
);
foreach ( $values_to_bring_back as $key ) {
if ( $option[ $key ] === '' && $this->defaults[ $key ] !== '' ) {
$option[ $key ] = $this->defaults[ $key ];
}
}
update_option( $this->option_name, $option );
}
}